package com.sailor.excel.httpclient.monitor;

import com.alibaba.ttl.TransmittableThreadLocal;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;

import java.io.Serializable;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;


/**
 * @description: 任务上下文
 * @author: wwz
 * @date: 2025-05-15 10:44
 */
@Data
@Slf4j
public class TaskMetricContext implements Serializable {

    private static TransmittableThreadLocal<Metrics> threadLocal = new TransmittableThreadLocal<>();

    /**
     * 获取当前任务统计信息,考虑到有重入情况
     * @param clazz
     * @param start
     * @param name
     * @return
     */
    public static Metrics getOrCreate(Class clazz,Date start,String name){
        Metrics metrics = null;
        try {
            metrics = get();
            if(null == metrics){
                metrics = Metrics.create(name,start);
                set(metrics);
            }
        } catch (Exception e){
            log.error("TaskMetricContext init err,clazz:{}",clazz, e);
        }
        return metrics;
    }

    /**
     * 当前新增数据时,记录新增数据总数
     * @param clazz
     * @param size
     */
    public static void increment(Class clazz,int size){
        try {
            if(0 == size) {
                return;
            }

            Metrics metrics = get();
            if(ObjectUtils.isNotEmpty(metrics)){
                metrics.getIncrement().addAndGet(size);
            }
        } catch (Exception e){
            log.error("TaskMetricContext increment err,clazz:{}",clazz, e);
        }
    }

    /**
     * 当前删除数据时,记录删除数据总数
     * @param clazz
     * @param size
     */
    public static void decrement(Class clazz, int size){
        try {
            if(0 == size) {
                return;
            }
            Metrics metrics = get();
            if(ObjectUtils.isNotEmpty(metrics)){
                metrics.getDecrement().addAndGet(size);
            }
        } catch (Exception e){
            log.error("TaskMetricContext delete err,clazz:{}",clazz, e);
        }
    }

    public static void remove(){
        try {
            threadLocal.remove();
        } catch (Exception e){
            log.error("TaskMetricContext remove() err", e);
        }
    }

    public static Metrics get(){
        return threadLocal.get();
    }

    public static void set(Metrics metrics){
         threadLocal.set(metrics);
    }


    @Data
    public static class Metrics {
        private String name;

        private Date start;

        private AtomicLong increment = new AtomicLong(0);

        private AtomicLong decrement = new AtomicLong(0);

        public static Metrics create(String name,Date start) {
            Metrics metrics = new Metrics();
            metrics.setName(name);
            metrics.setStart(start);
            return metrics;
        }
    }
}
